#include <stdio.h>
#include "RWLock.h"
#include <pthread.h>
#define CANT_THREADS 5
RWLock l;
  pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
int numeros[5];
int botellas[5];
int entregadas[5];

void *lecturas(void *p_minumero){
    int minumero = *((int *) p_minumero);
    pthread_mutex_unlock(&mutex);
    srand (time(NULL));
    int random;
    int valores[5];
    for (int i = 0 ; i <  20; i ++){
        l.rlock();
        for (int j = 0 ; j <  5; j ++){
            valores[j] = numeros[j];
        }

        printf("Soy el thread nro. %d. El arreglo tiene los valores: %d, %d, %d, %d, %d \n", minumero, valores[0], valores[1], valores[2], valores[3], valores[4]);
        l.runlock();
        random = rand() % 5 +1;
        usleep(random);
    }

    return NULL;
}

void *vendedor(void *p_minumero){
    int minumero = *((int *) p_minumero);
    pthread_mutex_unlock(&mutex);
    srand (time(NULL));
    int random;
    int cuantas;
    for (int i = 0 ; i <  30; i ++){
        random = rand() % 5 +1;
        l.wlock();
        botellas[minumero] = botellas[minumero] - 1;
        entregadas[minumero] = entregadas[minumero] +1;
        cuantas = 0;
        if (botellas[minumero] > 0){
        cuantas = rand() % botellas[minumero] / 20 ;
        }
        botellas[minumero] = botellas[minumero] - cuantas;
        i = i + cuantas;
        l.wunlock();

        usleep(random);
    }

    return NULL;
}

void *reporte(void *p_minumero){
    int minumero = *((int *) p_minumero);
    pthread_mutex_unlock(&mutex);
    srand (time(NULL));
    int random;
    int reportadas;
    int restantes;

    for (int i = 0 ; i <  100; i ++){
        l.rlock();
        restantes = botellas[minumero];
        reportadas = entregadas[minumero];
        if (restantes <= 0){
             printf("Soy el reportero nro. %d. El vendedor se quedo sin botellas y entrego %d. \n", minumero, reportadas);
             if (reportadas != 30) {
                printf("El vendedor nro. %d se tomo todo.\n \n", minumero);    
         
            }
             else {
                printf("El vendedor nro. %d si es honesto.\n \n", minumero);    
         
            }
             i = 100;
        }
        else{
            printf("Soy el reportero nro. %d. El vendedor todavia tiene botellas. \n", minumero);
        }
        l.runlock();
        random = rand() % 5 +1;
        usleep(random * 75);

    }

    return NULL;
}

int main(int argc, char **argv){
//test lectura

int tid;

    pthread_mutex_init(&mutex, NULL);
        pthread_mutex_lock(&mutex);
    for (int i = 0; i < 5; i++){
    numeros[i] = i+1;
}

    pthread_t thread[CANT_THREADS];
    for (int tid = 0; tid < CANT_THREADS;++tid){
        pthread_create(&thread[tid], NULL, lecturas, &tid);
        pthread_mutex_lock(&mutex);
    }

//comienzo a escribir
    for (int i = 0 ; i < 15; i ++){
        l.wlock();
        for (int j = 0 ; j < 5; j++){
                numeros[j] = numeros[j] + 1;
        }

        printf ("Soy el escritor. Aumento en 1 los valores... \n");
        l.wunlock();
        usleep(3);
    }
    for (tid = 0; tid < CANT_THREADS; ++tid){
        pthread_join(thread[tid], NULL);
    }
    printf ("Fin del test de lectura. \n");

printf("//////////////////////////////////////////////\n");
//test escritura

    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_lock(&mutex);
    for (int i = 0; i < 5; i++){
    botellas[i] = 30;
}

    for (int i = 0; i < 5; i++){
    entregadas[i] = 0;
}

    pthread_t thread1[CANT_THREADS];
    for (int tid = 0; tid < CANT_THREADS;++tid){
        pthread_create(&thread1[tid], NULL, vendedor, &tid);
        pthread_mutex_lock(&mutex);
    }

    pthread_t thread2[CANT_THREADS];
    for (int tid = 0; tid < CANT_THREADS;++tid){
        pthread_create(&thread2[tid], NULL, reporte, &tid);
        pthread_mutex_lock(&mutex);
    }
//espero fin de threads
    for (tid = 0; tid < CANT_THREADS; ++tid){
        pthread_join(thread1[tid], NULL);
    }
    for (tid = 0; tid < CANT_THREADS; ++tid){
        pthread_join(thread2[tid], NULL);
    }
    printf ("Fin del test de escritura. \n");
    return 0;
}